/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.jm.mala.util;

/**
 *
 * @author joao
 */
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.*;
import java.text.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManagerFactory;
import javax.servlet.http.*;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.comparators.ComparatorChain;

/**
 *
 * @author joao
 */
public class Funcoes implements Serializable {

    private static final long serialVersionUID = 1L;
    private int nErro;
    private HttpSession session = null;
    private final Statement declaracao = null;
    private final PreparedStatement declPreparada = null;
    private ResultSet resultado = null;
    private ResultSet rs = null;
    private final String pesquisa = null;
    private final String atualiza = null;
    private final Connection conexao = null;
    private final int ret = -1;
    private final int nId = 0;

    //-------- Valida CPF ou CNPJ
    public boolean valida_CpfCnpj(String s_aux) throws IOException {
        s_aux = TiraNull(s_aux);
        s_aux = s_aux.replace(".", "");
        s_aux = s_aux.replace("/", "");
        s_aux = s_aux.replace("-", "");
//------- Rotina para CPF        
        if (s_aux.length() == 11) {
            int d1, d2;
            int digito1, digito2, resto;
            int digitoCPF;
            String nDigResult;
            d1 = d2 = 0;
            digito1 = digito2 = resto = 0;
            for (int n_Count = 1; n_Count < s_aux.length() - 1; n_Count++) {
                digitoCPF = Integer.valueOf(s_aux.substring(n_Count - 1, n_Count)).intValue();
//--------- Multiplique a ultima casa por 2 a seguinte por 3 a seguinte por 4 e assim por diante. 
                d1 = d1 + (11 - n_Count) * digitoCPF;
//--------- Para o segundo digito repita o procedimento incluindo o primeiro digito calculado no passo anterior. 
                d2 = d2 + (12 - n_Count) * digitoCPF;
            }

//--------- Primeiro resto da divis�o por 11. 
            resto = (d1 % 11);
//--------- Se o resultado for 0 ou 1 o digito � 0 caso contr�rio o digito � 11 menos o resultado anterior. 
            if (resto < 2) {
                digito1 = 0;
            } else {
                digito1 = 11 - resto;
            }
            d2 += 2 * digito1;
//--------- Segundo resto da divis�o por 11. 
            resto = (d2 % 11);
//--------- Se o resultado for 0 ou 1 o digito � 0 caso contr�rio o digito � 11 menos o resultado anterior. 
            if (resto < 2) {
                digito2 = 0;
            } else {
                digito2 = 11 - resto;//--------- Digito verificador do CPF que est� sendo validado. 
            }
            String nDigVerific = s_aux.substring(s_aux.length() - 2, s_aux.length());
//--------- Concatenando o primeiro resto com o segundo. 
            nDigResult = String.valueOf(digito1) + String.valueOf(digito2);
//--------- Comparar o digito verificador do cpf com o primeiro resto + o segundo resto. 
            return nDigVerific.equals(nDigResult);
        } //-------- Rotina para CNPJ         
        else if (s_aux.length() == 14) {
            int soma = 0, aux, dig;
            String cnpj_calc = s_aux.substring(0, 12);
            char[] chr_cnpj = s_aux.toCharArray();
//--------- Primeira parte 
            for (int i = 0; i < 4; i++) {
                if (chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9) {
                    soma += (chr_cnpj[i] - 48) * (6 - (i + 1));
                }
            }
            for (int i = 0; i < 8; i++) {
                if (chr_cnpj[i + 4] - 48 >= 0 && chr_cnpj[i + 4] - 48 <= 9) {
                    soma += (chr_cnpj[i + 4] - 48) * (10 - (i + 1));
                }
            }
            dig = 11 - (soma % 11);
            cnpj_calc += (dig == 10 || dig == 11) ? "0" : Integer.toString(dig);
//--------- Segunda parte 
            soma = 0;
            for (int i = 0; i < 5; i++) {
                if (chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9) {
                    soma += (chr_cnpj[i] - 48) * (7 - (i + 1));
                }
            }
            for (int i = 0; i < 8; i++) {
                if (chr_cnpj[i + 5] - 48 >= 0 && chr_cnpj[i + 5] - 48 <= 9) {
                    soma += (chr_cnpj[i + 5] - 48) * (10 - (i + 1));
                }
            }
            dig = 11 - (soma % 11);
            cnpj_calc += (dig == 10 || dig == 11) ? "0" : Integer.toString(dig);
            return s_aux.equals(cnpj_calc);
        } else {
            return false;
        }
    }

    public boolean converteStringBoolean(String cPalavra) {
        boolean bool = new Boolean(cPalavra);
        return bool;
    }

    public BigDecimal criaBigDecimal(String s) {
        try {
            if (s == null) {
                s = "0,00";
            } else if (s.trim().length() <= 0) {
                s = "0,00";
            }
            s = s.replace(".", "");
            s = s.replace(",", ".");

            return new BigDecimal(s);
        } catch (NumberFormatException e) {
            s = "0,00";
            return new BigDecimal(s);
        }
    }

    public boolean ValidaData(String cData) {
        Date data = null;
        String dataTexto = cData;
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");

        format.setLenient(false);
        try {
            data = format.parse(dataTexto);
            return true;
        } catch (ParseException ex) {
            return false;
        }
    }

    public java.sql.Date ConverteDataSql(String cData) {
        java.sql.Date data = null;
        DateFormat fmt = new SimpleDateFormat("dd/MM/yyyy");
        try {
            data = new java.sql.Date(fmt.parse(cData).getTime());
        } catch (ParseException ex) {
            data = null;
        }

        return data;
    }

    public java.util.Date ConverteData(String cData) {
        Date data = null;
        String dataTexto = cData;
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");

        format.setLenient(false);
        try {
            data = format.parse(dataTexto);
            return data;
        } catch (ParseException ex) {
            return null;
        }
    }

    public boolean ComparaData(Date dInicial, Date dFinal) {
        boolean lReturn = false;
        try {
            if (dInicial == null && dFinal == null) {
                lReturn = false;
            } else if (dInicial.compareTo(dFinal) != 0) {
                lReturn = true;
            } else {
                lReturn = false;
            }

            return lReturn;
        } catch (Exception e) {
            return true;
        }
    }

    public boolean ComparaString(String dInicial, String dFinal) {
        boolean lReturn = false;
        try {
            if (dInicial == null && dFinal == null) {
                lReturn = false;
            } else if (dInicial == null && dFinal.isEmpty()) {
                lReturn = false;
            } else if (dInicial.compareTo(dFinal) != 0) {
                lReturn = true;
            } else {
                lReturn = false;
            }

            return lReturn;
        } catch (Exception e) {
            return true;
        }
    }

    public String ConverteDateString(java.util.Date dDate) {
        DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
        String minhaData = "";
        //Ateno para isto:   
        df.setLenient(false);
        try {
            minhaData = df.format(dDate);
        } catch (Exception ex) {
            return "";
        }
        return minhaData;
    }

    public int ConverteInteiro(String cNumero) {
        nErro = 0;
        try {
            nErro = Integer.parseInt(cNumero);
        } catch (Exception ex) {
            nErro = 0;
        }
        return nErro;
    }

    public long ConverteLong(String cNumero) {
        long nReturn = 0;
        try {
            nReturn = Long.parseLong(cNumero);
        } catch (Exception ex) {
            nReturn = 0;
        }
        return nReturn;
    }

    public double ConverteDouble(String cNumero) {
        double nReturn = 0;
        try {
            nReturn = Double.parseDouble(cNumero);
        } catch (Exception ex) {
            nReturn = 0;
        }
        return nReturn;
    }

    public String ConverteString(int cNumero) {
        String cErro = "";
        try {
            cErro = Integer.toString(cNumero);
        } catch (Exception ex) {
            cErro = "";
        }
        return cErro;
    }

    public String TiraNull(String cPalavra) throws IOException {
        if (cPalavra == null) {
            cPalavra = "";
        } else {
            cPalavra = cPalavra.trim();
        }
        //String cRetorno = new String(cPalavra.getBytes("UTF-8"), "ISO-8859-1");
        return cPalavra;
    }

    public boolean StrEmpty(String cPalavra) throws IOException {
        cPalavra = TiraNull(cPalavra);
        if (cPalavra.length() == 0) {
            return true;
        } else {
            return false;
        }
    }

    public static String getValueMaskFormat(String pMask, String pValue, boolean lTroca) {


        /* 
         * Formata valor com a mascara passada  
         */
        if (lTroca) {
            pValue = pValue.replace(".", ",");
        }
        for (int i = 0; i < pValue.length(); i++) {
            pMask = pMask.replaceFirst("#", pValue.substring(i, i + 1));
        }

        /* 
         * Subistitui por string vazia os digitos restantes da mascara 
         * quando o valor passado é menor que a mascara   
         */
        return pMask.replaceAll("#", "");
    }

    public String FormataValor(BigDecimal nValor, int nDecimal) {
        String cValor = "";
        try {
            //NumberFormat moeda1 = NumberFormat.getNumberInstance();
            NumberFormat moedaFormat = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
            moedaFormat.setMinimumFractionDigits(nDecimal);
            moedaFormat.setMaximumFractionDigits(nDecimal);
            cValor = moedaFormat.format(nValor);
        } catch (Exception ex) {
            if (nDecimal > 0) {
                cValor = "";
                for (int i = 0; i < nDecimal; i++) {
                    cValor = cValor = "0," + "0";
                }
            } else {
                cValor = "0";
            }
        }
        return cValor;
    }

    public String FormataValorFloat(float nValor, int nDecimal) {
        String cValor = "";
        try {
            NumberFormat moeda1 = NumberFormat.getNumberInstance(new Locale("pt", "BR"));
            moeda1.setMinimumFractionDigits(nDecimal);
            moeda1.setMaximumFractionDigits(nDecimal);
            cValor = moeda1.format(nValor);
        } catch (Exception ex) {
            if (nDecimal > 0) {
                cValor = "";
                for (int i = 0; i < nDecimal; i++) {
                    cValor = cValor = "0," + "0";
                }
            } else {
                cValor = "0";
            }
        }
        return cValor;
    }

    public String TiraCaractere(String cValor, String[] aCaractere) {
        for (int i = 0; i < aCaractere.length; i++) {
            cValor = cValor.replace(aCaractere[i], "");
        }
        return cValor;
    }

    public boolean PesqCaracteres(String cValor, String[] aCaractere) {
        boolean lReturn = false;
        try {
            for (int i = 0; i < aCaractere.length; i++) {
                lReturn = cValor.indexOf(aCaractere[i]) > -1;
                if (lReturn) {
                    break;
                }
            }
        } catch (Exception e) {
            lReturn = false;
        }
        return lReturn;
    }

    public String iif(boolean lOperacao, String cCampo1, String cCampo2) {
        if (lOperacao) {
            return cCampo1;
        } else {
            return cCampo2;
        }
    }

    public boolean iifBoolean(boolean lOperacao, boolean cCampo1, boolean cCampo2) {
        if (lOperacao) {
            return cCampo1;
        } else {
            return cCampo2;
        }
    }

    public BigDecimal iifBigDecimal(boolean lOperacao, BigDecimal cCampo1, BigDecimal cCampo2) {
        if (lOperacao) {
            return cCampo1;
        } else {
            return cCampo2;
        }
    }

    public String RetornSN(String cPalavra) {
        cPalavra = cPalavra.toLowerCase();
        if (cPalavra.equals("false") || cPalavra.equals("N")) {
            cPalavra = "N";
        } else {
            cPalavra = "S";
        }
        return cPalavra;
    }

    public String FormataCPFCNPF(String nCnpj, String cTip_Pessoa) {
        if (nCnpj == null) {
            nCnpj = " ";
        } else if (cTip_Pessoa.equals("J")) {
            nCnpj = nCnpj.substring(0, 2) + "." + nCnpj.substring(2, 5) + "." + nCnpj.substring(5, 8) + "/" + nCnpj.substring(8, 12) + "-" + nCnpj.substring(12, 14);
        } else {
            nCnpj = nCnpj.substring(0, 3) + "." + nCnpj.substring(3, 6) + "." + nCnpj.substring(6, 9) + "-" + nCnpj.substring(9, 11);
        }
        return nCnpj;
    }

    public ResultSet RetornaRS(String cSelect, Connection conexao) throws SQLException {
        try {
            PreparedStatement ps = null;
            rs = null;

            ps = conexao.prepareStatement(cSelect);
            rs = ps.executeQuery();
        } catch (SQLException e) {
            resultado = null;
        }

        return resultado;
    }

    public String toISO88591(String text) throws Exception {
        byte p[] = text.getBytes("UTF-8");
        return new String(p, 0, p.length, "ISO-8859-1");
    }

    /* para tratar os caracteres recebidos */
    public String toUTF8(String text) throws Exception {
        byte p[] = text.getBytes("iso-8859-1");
        return new String(p, 0, p.length, "UTF-8");
    }

    public void ImprimeDadosJSON(ArrayList<String> lDados, PrintWriter out) {
        int nCount = lDados.size();
        String cDados = lDados.get(nCount - 1).toString();
        StringBuilder sb = new StringBuilder(cDados);
        sb.ensureCapacity(sb.length() + 2);
        sb.replace(sb.length() - 1, sb.length() + 2, "],");
        cDados = sb.toString();
        lDados.set(nCount - 1, cDados);
        lDados.set(nCount - 1, cDados);
        for (int i = 0; i < nCount; i++) {
            out.println(lDados.get(i));
        }
    }

    public String RetCharSet(String str) throws IOException, Exception {
        String cTabela = "-_)(*&¨%$#@!'\"\\|/?;:.>,<[{]}0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzçÇáàâãÁÀÂÃéèêÉÈÊíìÍÌóòôõÓÒÔÕúùûÚÙÛ ";
        char[] charsTab = cTabela.toCharArray();
        char[] cPalavra = str.toCharArray();

        int cCodTab;
        int cCodPal;
        String cEncode = "UTF-8";

        char cLetTab;
        char cLetPal;

        boolean lPassa = false;

        for (int i = 0; i < cPalavra.length; ++i) {
            cCodPal = (int) cPalavra[i];
            cLetPal = cPalavra[i];
            for (int j = 0; j < charsTab.length; ++j) {
                cCodTab = (int) charsTab[j];
                cLetTab = charsTab[j];
                if (cCodTab == cCodPal) {
                    if (cLetTab == cLetPal) {
                        lPassa = true;
                        break;
                    } else {
                        lPassa = false;
                    }
                } else {
                    lPassa = false;
                }
            }
            if (!lPassa) {
                break;
            }
        }
        if (!lPassa) {
            cEncode = "N/A";
        }

        return cEncode;
    }

    public String getRandomPass(int len) {
        char[] chart = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

        char[] senha = new char[len];

        int chartLenght = chart.length;
        Random rdm = new Random();

        for (int i = 0; i < len; i++) {
            senha[i] = chart[rdm.nextInt(chartLenght)];
        }

        return new String(senha);
    }

    public String criptografaSenha(String senha) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        BigInteger hash = new BigInteger(1, md.digest(senha.getBytes()));
        String s = hash.toString(16);
        if (s.length() % 2 != 0) {
            s = "0" + s;
        }
        return s;
    }

    public void addMessage(String summary, String msg) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, summary, msg);
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    public EntityManagerFactory retornaEMF() {
        EntityManagerFactory emf = null;
        FacesContext ctx = FacesContext.getCurrentInstance();
        session = (HttpSession) ctx.getExternalContext().getSession(true);
        emf = (EntityManagerFactory) session.getAttribute("emf");

        return emf;
    }

    /**
     * Calcula a diferença de duas datas em dias <br> <b>Importante:</b> Quando
     * realiza a diferença em dias entre duas datas, este método considera as
     * horas restantes e as converte em fração de dias.
     *
     * @param dataInicial
     * @param dataFinal
     * @return quantidade de dias existentes entre a dataInicial e dataFinal.
     */
    public static int diferencaEmMeses(Date dataInicial, Date dataFinal) {
        int result = 0;

        GregorianCalendar calendar = new GregorianCalendar();

        calendar.setTime(dataInicial);
        int mesInicial = calendar.get(GregorianCalendar.MONTH) + 1;

        calendar.setTime(dataFinal);
        int mesFinal = calendar.get(GregorianCalendar.MONTH) + 1;

        result = mesFinal - mesInicial;

        return result;
    }

    /**
     * Calcula a diferença de duas datas em dias <br> <b>Importante:</b> Quando
     * realiza a diferença em dias entre duas datas, este método considera as
     * horas restantes e as converte em fração de dias.
     *
     * @param dataInicial
     * @param dataFinal
     * @return quantidade de dias existentes entre a dataInicial e dataFinal.
     */
    public static double diferencaEmDias(Date dataInicial, Date dataFinal) {
        double result = 0;
        long diferenca = dataFinal.getTime() - dataInicial.getTime();
        double diferencaEmDias = (diferenca / 1000) / 60 / 60 / 24; //resultado é diferença entre as datas em dias  
        long horasRestantes = (diferenca / 1000) / 60 / 60 % 24; //calcula as horas restantes  
        result = diferencaEmDias + (horasRestantes / 24d); //transforma as horas restantes em fração de dias  

        return result;
    }

    /**
     * Calcula a diferença de duas datas em horas <br> <b>Importante:</b> Quando
     * realiza a diferença em horas entre duas datas, este método considera os
     * minutos restantes e os converte em fração de horas.
     *
     * @param dataInicial
     * @param dataFinal
     * @return quantidade de horas existentes entre a dataInicial e dataFinal.
     */
    public static double diferencaEmHoras(Date dataInicial, Date dataFinal) {
        double result = 0;
        long diferenca = dataFinal.getTime() - dataInicial.getTime();
        long diferencaEmHoras = (diferenca / 1000) / 60 / 60;
        long minutosRestantes = (diferenca / 1000) / 60 % 60;
        double horasRestantes = minutosRestantes / 60d;
        result = diferencaEmHoras + (horasRestantes);

        return result;
    }

    /**
     * Calcula a diferença de duas datas em minutos <br> <b>Importante:</b>
     * Quando realiza a diferença em minutos entre duas datas, este método
     * considera os segundos restantes e os converte em fração de minutos.
     *
     * @param dataInicial
     * @param dataFinal
     * @return quantidade de minutos existentes entre a dataInicial e dataFinal.
     */
    public static double diferencaEmMinutos(Date dataInicial, Date dataFinal) {
        double result = 0;
        long diferenca = dataFinal.getTime() - dataInicial.getTime();
        double diferencaEmMinutos = (diferenca / 1000) / 60; //resultado é diferença entre as datas em minutos  
        long segundosRestantes = (diferenca / 1000) % 60; //calcula os segundos restantes  
        result = diferencaEmMinutos + (segundosRestantes / 60d); //transforma os segundos restantes em minutos  

        return result;
    }

    public static BigDecimal calcularMontanteJuroComposto(BigDecimal capital, BigDecimal taxa, int tempo) {
        return capital.multiply(taxa.add(BigDecimal.ONE).pow(tempo));
    }

    public static BigDecimal calcularMontanteJuroSimples(BigDecimal capital, BigDecimal taxa, int tempo) {
        return capital.add(capital.multiply(taxa).multiply(new BigDecimal(tempo)));
    }

    public String retornaPedido(String cPedido) {
        String cBunda = "bunda";
        return cBunda;
    }

    public boolean validaEmail(String email) {
        boolean lReturn = true;

        if (!email.isEmpty()) {
            Pattern p = Pattern.compile("^[\\w\\-]+(\\.[\\w\\-]+)*@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$");
            Matcher m = p.matcher(email);

            boolean matchFound = m.matches();

            if (!matchFound) {
                lReturn = false;
            }
        } else {
            lReturn = false;
        }

        return lReturn;
    }

    /**
     * Character Description # Qualquer numero valido.
     *
     * ' Usado para não usar nenhum caracter especial na formatacao ("\n",
     * "\t"....)
     *
     * U Qualquer caracter Todas as letras minusculas sao passadas para
     * maiuscula.
     *
     * L Qualquer caracter Todas as letras maiusculas sao passadas para
     * minusculas
     *
     * A Qualquer caracter ou numero ( Character.isLetter or Character.isDigit )
     *
     * ? Qualquer caracter ( Character.isLetter ).
     *
     *  * Qualquer Coisa.
     *
     * H Qualquer caracter hexa (0-9, a-f ou A-F).
     *
     * ==================================== ex: value = "A1234B567Z" mask =
     * "A-AAAA-AAAA-A" output : A-1234-B567-Z
     *
     * ===================================
     *
     * @param string
     * @param mask
     * @return
     * @throws java.text.ParseException
     */
    public String formatString(String string, String mask) throws ParseException {
        javax.swing.text.MaskFormatter mf = new javax.swing.text.MaskFormatter(mask);
        mf.setValueContainsLiteralCharacters(false);
        return mf.valueToString(string);
    }

    public static boolean isValidDate(Object object, boolean obrigatorio, boolean dataEHora) {

        //Verifica se o objeto passado é string ou java.util.Date
        //Preenche a string a ser usada na validação
        String dataString = null;
        if (object instanceof String) {
            dataString = object.toString();
        } else if (object instanceof Date) {
            SimpleDateFormat out = null;
            if (dataEHora) {
                out = new SimpleDateFormat("ddMMyyyyHHmmss");
                dataString = out.format(object);
            } else {
                out = new SimpleDateFormat("ddMMyyyy");
                dataString = out.format(object);
            }
        }

        //Verifica se é obrigatório e o campo não foi preenchido
        if (obrigatorio && isEmpty(dataString)) {
            return false;
        } else //Verifica se não for obrigatório e o campo não foi preenchido
        if (!obrigatorio && isEmpty(dataString)) {
            return true;
        }

        //Retira todos os caracteres que não forem numéricos
        dataString = dataString.replaceAll("[^\\d]", "");

        //Se campo possui hora, deve possuir pelo menos 14 dígitos
        if (dataEHora && dataString.length() < 14) {
            return false;
        }

        //Se campo não possui hora, deve possuir pelo menos 8 digitos
        if (!dataEHora && dataString.length() < 8) {
            return false;
        }

        //Pega os valores do dia, mês e ano
        Long dia = new Long(dataString.substring(0, 2));
        Long mes = new Long(dataString.substring(2, 4));
        Long ano = new Long(dataString.substring(4, 8));

        Long hora = null;
        Long minuto = null;
        Long segundo = null;

        //Se data tem hora pega os valores de horas, minutos e segundos.
        if (dataEHora) {
            hora = new Long(dataString.substring(8, 10));
            minuto = new Long(dataString.substring(10, 12));
            segundo = new Long(dataString.substring(12, 14));
        }

        try {
            //Preenche um objeto GregorianCalendar onde a validação acontece
            //Inclusive sobre ano bisexto, dia inválido, hora inválida
            GregorianCalendar data = new GregorianCalendar();
            data.setLenient(false);
            data.set(GregorianCalendar.YEAR, ano.intValue());
            data.set(GregorianCalendar.MONTH, mes.intValue() - 1);
            data.set(GregorianCalendar.DATE, dia.intValue());

            if (dataEHora) {
                data.set(GregorianCalendar.HOUR_OF_DAY, hora.intValue());
                data.set(GregorianCalendar.MINUTE, minuto.intValue());
                data.set(GregorianCalendar.SECOND, segundo.intValue());
            }

            // A validação da data ocorre aqui
            // Caso tenha alguma coisa errada com a data o sistema lança exceção
            // Capturada pelo catch abaixo e retorna false
            data.getTime();
        } catch (Exception e) {
            return false;
        }
        return true;

    }

    //Método para verificar se string é vazia
    public static boolean isEmpty(String s) {
        return ((s == null) || ("".equals(s.trim())));
    }

    public static boolean isEmptyList(List s) {
        boolean lReturn = false;
        if (s == null) {
            lReturn = true;
        } else if (s.isEmpty()) {
            lReturn = true;
        }

        return lReturn;
    }

    // Retorna o nome do mês.
    // Parâmetros: "i" = índice para o vetor "mes"
    //             "tipo" = 0 para retornar o nome completo e
    //                      1 para o nome abreviado do mês.
    public static String NomeDoMes(int i, int tipo) {
        String mes[] = {"Janeiro", "Fevereiro", "Março", "Abril",
            "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"};
        // Java é uma linguagem com vetores zero-based: as posições do vetor
        // iniciam a numeração a partir do valor 0 (0-janeiro, 1-fevereiro, ...)
        if (tipo == 0) {
            return (mes[i - 1]); // extenso
        }// o método "substring" retorna os 3 primeiros caracteres de "mes[i-1]"
        else {
            return (mes[i - 1].substring(0, 3)); // abreviado
        }
    }

// Retorna o dia da semana.
// Parâmetros: "i" = índice para o vetor "diasem"
//             "tipo" = 0 para retornar o nome completo e
//                      1 para o nome abreviado do dia da semana.
    public static String DiaDaSemana(int i, int tipo) {
        String diasem[] = {"domingo", "segunda-feira", "terça-feira",
            "quarta-feira", "quinta-feira", "sexta-feira", "sábado"};
        if (tipo == 0) {
            return (diasem[i - 1]); // extenso
        }// o método "substring" retorna os 3 primeiros caracteres de "diasem[i]"
        else {
            return (diasem[i - 1].substring(0, 3));
        }
    }

// Retorna a data por extenso.
// Parâmetros: "cidade" = nome da cidade; e, "dt" = data.
    public static String DataPorExtenso(String cidade, java.util.Date dt) {
// retorna os valores ano, mês e dia da variável "dt"
        int d = dt.getDate();
        int m = dt.getMonth() + 1;
        int a = dt.getYear() + 1900;

// retorna o dia da semana: 1=domingo, 2=segunda-feira, ..., 7=sábado
        Calendar data = new GregorianCalendar(a, m - 1, d);
        int ds = data.get(Calendar.DAY_OF_WEEK);

        String cData;

        if (cidade.equals("#")) {
            cData = (d + " de " + NomeDoMes(m, 0) + " de "
                    + a);
        } else {
            cData = (cidade + ", " + d + " de " + NomeDoMes(m, 0) + " de "
                    + a);
        }
        cData += ".";
        return cData;
    }

    public String retornaZero(String cNumero) {
        int numero;
        String cAno;

        cAno = cNumero.substring(3);
        numero = Integer.parseInt(cNumero.substring(0, 3)) + 1;
        String cRetorno = String.format("%03d", numero);
        cRetorno += cAno;

        return cRetorno;
    }

    public String tiraMacro(String cMacro) {
        List<String> results = new ArrayList<String>();

        cMacro = cMacro.replace("R$", "");

        results.add("#VALOR_ETAPA1#1#");
        results.add("#VALOR_ETAPA1#2#");
        results.add("#VALOR_ETAPA1#3#");
        results.add("#VALOR_ETAPA1#4#");
        results.add("#VALOR_ETAPA1#5#");
        results.add("#VALOR_ETAPA2#1#");
        results.add("#VALOR_ETAPA2#2#");
        results.add("#VALOR_ETAPA2#3#");
        results.add("#VALOR_ETAPA2#4#");
        results.add("#VALOR_ETAPA2#5#");
        results.add("#VALOR_ETAPA3#1#");
        results.add("#VALOR_ETAPA3#2#");
        results.add("#VALOR_ETAPA3#3#");
        results.add("#VALOR_ETAPA3#4#");
        results.add("#VALOR_ETAPA3#5#");
        results.add("#VALOR_ETAPA4#1#");
        results.add("#VALOR_ETAPA4#2#");
        results.add("#VALOR_ETAPA4#3#");
        results.add("#VALOR_ETAPA4#4#");
        results.add("#VALOR_ETAPA4#5#");
        results.add("#VALOR_ETAPA5#1#");
        results.add("#VALOR_ETAPA5#2#");
        results.add("#VALOR_ETAPA5#3#");
        results.add("#VALOR_ETAPA5#4#");
        results.add("#VALOR_ETAPA5#5#");

        for (int i = 0; i < results.size(); i++) {
            cMacro = cMacro.replace(results.get(i), "");
        }

        cMacro = cMacro.trim();

        return cMacro;

    }

    public boolean compareDatesByCompareTo(Date oldDate, Date newDate, String cTipo) {
        /* 
         cTipo = I = Igual
         M - Menor
         R - Maior
         */
        boolean lReturn = false;
        try {
            if (oldDate.compareTo(newDate) == 0) {
                //Como para verificar se date1 é igual a date2
                //if (cTipo.equals("I")) {
                lReturn = true;
                //}
            } else if (oldDate.compareTo(newDate) < 0) {
                //Verificando se date1 é menor que data2
                if (cTipo.equals("M")) {
                    lReturn = true;
                }
            } else if (oldDate.compareTo(newDate) > 0) {
                //Como para verificar se data1 é maior do que date2 em java
                if (cTipo.equals("R")) {
                    lReturn = true;
                }
            }
        } catch (Exception e) {
            lReturn = false;
        }
        return lReturn;
    }

    public boolean compareDatesByDateMethods(Date oldDate, Date newDate, String cTipo) {
        /* 
         cTipo = I = Igual
         M - Menor
         R - Maior
         */
        boolean lReturn = false;

        if (oldDate.equals(newDate)) {
            //Como para verificar se date1 é igual a date2
            if (cTipo.equals("I")) {
                lReturn = true;
            }
        } else if (oldDate.before(newDate)) {
            //Verificando se date1 é menor que data2
            if (cTipo.equals("M")) {
                lReturn = true;
            }
        } else if (oldDate.after(newDate)) {
            //Como para verificar se data1 é maior do que date2 em java
            if (cTipo.equals("R")) {
                lReturn = true;
            }
        }

        return lReturn;
    }

    public String repete(String string, int quantidade) {
        StringBuilder retorno = new StringBuilder();
        for (int j = 0; j < quantidade; j++) {
            retorno.append(string);
        }

        return retorno.toString();
    }

    public List ordenaList(List listOrdena, List listCampos) {
        List sortFields = new ArrayList();
        listCampos.stream().forEach((listCampo) -> {
            sortFields.add(new BeanComparator((String) listCampo));
        });
        ComparatorChain multiSort = new ComparatorChain(sortFields);

        java.util.Collections.sort(listOrdena, multiSort);

        return listOrdena;
    }
}
